/**
 * 描述: 业务逻辑处理 - 任务相关接口
 * 作者: Jack Chen
 * 日期: 2020-06-20
 */

const { querySql, queryOne } = require("../utils/index");
const jwt = require("jsonwebtoken");
const boom = require("boom");
const { validationResult } = require("express-validator");
const { CODE_ERROR, CODE_SUCCESS, CODE_TOKEN_EXPIRED, CODE_FORBIDDEN } = require("../utils/constant");
const { decode } = require("../utils/user-jwt");
const crypto = require("crypto"); // 引入crypto加密模块
const dayjs = require("dayjs");
const { encrypt } = require("../utils/md5");

// 查询列表
function queryPage(req, res, next) {
  const err = validationResult(req);
  // 如果验证错误，empty不为空
  if (!err.isEmpty()) {
    // 获取错误信息
    const [{ msg }] = err.errors;
    // 抛出错误，交给我们自定义的统一异常处理程序进行错误返回
    next(boom.badRequest(msg));
  } else {
    // 新增类型查询
    let { pageSize, pageNo, status, token, key, createTimeStart, createTimeEnd, type } = req.query;
    // 默认值
    pageSize = pageSize ? pageSize : 1;
    pageNo = pageNo ? pageNo : 1;
    // let query = `select * from account where status=${status === undefined ? 1 : status}`;
    let str = "";
    if (token) {
      str = `and a.token='${token.trim()}'`;
    }
    if (key) {
      str += ` and a.key = '${key.trim()}'`;
    }
    if (createTimeStart) {
      str += ` and a.createTime >= '${createTimeStart.trim()}'`;
    }
    if (createTimeEnd) {
      str += ` and a.createTime <= '${createTimeEnd.trim()}'`;
    }
    if (+type) {
      str += ` and a.type = ${type}`;
    }
    const query = `SELECT a.*,  ap.count AS pCount FROM account a LEFT JOIN  account_property ap ON a.key = ap.id WHERE
    a.status = ${status === undefined ? 1 : status} ${str} ORDER BY  a.createTime desc`;

    querySql(query)
      .then((data) => {
        // console.log('任务列表查询===', data);
        if (!data || data.length === 0) {
          res.json({
            code: CODE_SUCCESS,
            msg: "暂无数据",
            data: {
              rows: [],
              total: 0,
              pageNo: parseInt(pageNo),
              pageSize: parseInt(pageSize),
            },
          });
        } else {
          // 计算数据总条数
          let total = data.length;
          // 分页条件 (跳过多少条)
          let n = (pageNo - 1) * pageSize;
          // 拼接分页的sql语句命令
          let query_3 = query + ` limit ${n} , ${pageSize}`;
          querySql(query_3)
            .then((result_3) => {
              // console.log("分页2===", result_3);
              if (!result_3 || result_3.length === 0) {
                res.json({
                  code: CODE_SUCCESS,
                  msg: "暂无数据",
                  data: {
                    rows: [],
                    total: 0,
                    pageNo: parseInt(pageNo),
                    pageSize: parseInt(pageSize),
                  },
                });
              } else {
                // 转换时间格式
                res.json({
                  code: CODE_SUCCESS,
                  msg: "查询数据成功",
                  data: {
                    rows: result_3.map((v) => {
                      return {
                        ...v,
                        createTime: v.createTime ? dayjs(v.createTime).format("YYYY-MM-DD HH:mm:ss") : "",
                        pCount: v.pCount || 0,
                      };
                    }),
                    total: total,
                    pageNo: parseInt(pageNo),
                    pageSize: parseInt(pageSize),
                  },
                });
              }
            })
            .catch(() => {
              res.json({
                code: CODE_ERROR,
                msg: "查询失败",
                data: null,
              });
            });
        }
      })
      .catch(() => {
        res.json({
          code: CODE_ERROR,
          msg: "查询失败",
          data: null,
        });
      });
  }
}

// 查询列表
function queryAll(req, res, next) {
  const err = validationResult(req);
  // 如果验证错误，empty不为空
  if (!err.isEmpty()) {
    // 获取错误信息
    const [{ msg }] = err.errors;
    // 抛出错误，交给我们自定义的统一异常处理程序进行错误返回
    next(boom.badRequest(msg));
  } else {
    // 新增类型查询
    let { status, token, key, createTimeStart, createTimeEnd, type, maxUser } = req.query;
    // let query = `select * from account where status=${status === undefined ? 1 : status}`;
    let str = "";
    if (token) {
      str = `and a.token='${token.trim()}'`;
    }
    if (key) {
      str += ` and a.key = '${key.trim()}'`;
    }
    if (createTimeStart) {
      str += ` and a.createTime >= '${createTimeStart.trim()}'`;
    }
    if (createTimeEnd) {
      str += ` and a.createTime <= '${createTimeEnd.trim()}'`;
    }
    if (+type) {
      str += ` and a.type = ${type}`;
    }
    const query = `SELECT a.*,  ap.count AS pCount FROM account a LEFT JOIN  account_property ap ON a.key = ap.id WHERE
    a.status = ${status === undefined ? 1 : status} ${str} ORDER BY a.createTime desc`;

    querySql(query)
      .then((data) => {
        // console.log('任务列表查询===', data);
        if (!data || data.length === 0) {
          res.json({
            code: CODE_SUCCESS,
            msg: "暂无数据",
            data: [],
          });
        } else {
          res.json({
            code: CODE_SUCCESS,
            msg: "查询数据成功",
            data: {
              rows: data.map((v) => {
                return {
                  ...v,
                  createTime: v.createTime ? dayjs(v.createTime).format("YYYY-MM-DD HH:mm:ss") : "",
                  pCount: v.pCount || 0,
                };
              }),
              total: data.length,
            },
          });
        }
      })
      .catch(() => {
        res.json({
          code: CODE_ERROR,
          msg: "查询失败",
          data: null,
        });
      });
  }
}

// 添加任务
function add(req, res, next) {
  const err = validationResult(req);
  if (!err.isEmpty()) {
    const [{ msg }] = err.errors;
    next(boom.badRequest(msg));
  } else {
    const { key, token, guildId, channelId, count = 1, type, remark, maxUser = 12 } = req.body;

    const inset = (id) => {
      const query = `insert into account(\`key\`, token, guildId, channelId, status, maxUser, \`createTime\`, type, remark) values('${id}', '${token}', '${
        guildId || ""
      }', '${channelId || ""}', 1, ${maxUser}, '${dayjs().format("YYYY-MM-DDTHH:mm:ss")}', ${type || 0}, '${
        remark || ""
      }')`;
      querySql(query)
        .then((data) => {
          if (!data || data.length === 0) {
            res.json({
              code: CODE_ERROR,
              msg: "添加数据失败",
              data: null,
            });
          } else {
            res.json({
              code: CODE_SUCCESS,
              msg: "添加数据成功",
              data: null,
            });
          }
        })
        .catch((err) => {
          debugger;
          res.json({
            code: CODE_ERROR,
            msg: "添加数据失败",
            data: null,
          });
        });
    };

    // 判断是否批量
    if (count > 1) {
      let sqlStr = `insert into account(\`key\`, token, guildId, channelId, status, maxUser , \`createTime\`, type, remark) values `;
      const str = [...new Array(count)]
        .map(() => {
          return `('${crypto.randomUUID().replaceAll("-", "").slice(16)}', '${token}', '${guildId || ""}', '${
            channelId || ""
          }', 1, ${maxUser}, '${dayjs().format("YYYY-MM-DDTHH:mm:ss")}', ${type || 0}, '${remark}')`;
        })
        .join(",");

      querySql(sqlStr + str)
        .then((data) => {
          if (!data || data.length === 0) {
            res.json({
              code: CODE_ERROR,
              msg: "添加数据失败",
              data: null,
            });
          } else {
            res.json({
              code: CODE_SUCCESS,
              msg: "添加数据成功",
              data: null,
            });
          }
        })
        .catch(() => {
          res.json({
            code: CODE_ERROR,
            msg: "添加数据失败",
            data: null,
          });
        });
      return;
    }

    if (!key) {
      const str = crypto.randomUUID().replaceAll("-", "").slice(16);
      inset(str);
      return;
    }

    findTask(key).then((task) => {
      if (task) {
        res.json({
          code: CODE_ERROR,
          msg: "key不能重复",
          data: null,
        });
      } else {
        if (!token) {
          res.json({
            code: CODE_ERROR,
            msg: "token不能为空",
            data: null,
          });
          return;
        }
        inset(key);
      }
    });
  }
}

// 编辑任务
function edit(req, res, next) {
  const err = validationResult(req);
  if (!err.isEmpty()) {
    const [{ msg }] = err.errors;
    next(boom.badRequest(msg));
  } else {
    const { key: id, token, guildId = "", channelId = "", status, remark, maxUser } = req.body;
    let setStr = "";
    // 有备注修改备注
    if (remark !== undefined) {
      setStr += `, remark = '${remark}'`;
    }
    // 有maxUser修改maxUser
    if (maxUser) {
      setStr += `, maxUser = '${maxUser}'`;
    }
    findTask(id).then((task) => {
      if (task) {
        const query = `update account set token='${token}', guildId='${guildId}', channelId='${channelId}', status=${
          status === undefined ? task.status : status
        }${setStr} where \`key\`='${id}'`;
        querySql(query)
          .then((data) => {
            // console.log('编辑任务===', data);
            if (!data || data.length === 0) {
              res.json({
                code: CODE_ERROR,
                msg: "更新数据失败",
                data: null,
              });
            } else {
              res.json({
                code: CODE_SUCCESS,
                msg: "更新数据成功",
                data: null,
              });
            }
          })
          .catch((err) => {
            res.json({
              code: CODE_ERROR,
              msg: "参数错误或数据不存在",
              data: null,
            });
          });
      } else {
        res.json({
          code: CODE_ERROR,
          msg: "参数错误或数据不存在",
          data: null,
        });
      }
    });
  }
}

// 更新服务器和频道
function editBase(req, res, next) {
  const err = validationResult(req);
  if (!err.isEmpty()) {
    const [{ msg }] = err.errors;
    next(boom.badRequest(msg));
  } else {
    const { key: id, guildId = "", channelId = "" } = req.body;
    findTask(id).then((task) => {
      if (task) {
        const query = `update account set guildId='${guildId}', channelId='${channelId}' where \`key\`='${id}'`;
        querySql(query)
          .then((data) => {
            if (!data || data.length === 0) {
              res.json({
                code: CODE_ERROR,
                msg: "更新数据失败",
                data: null,
              });
            } else {
              res.json({
                code: CODE_SUCCESS,
                msg: "更新数据成功",
                data: null,
              });
            }
          })
          .catch((err) => {
            res.json({
              code: CODE_ERROR,
              msg: "参数错误或数据不存在",
              data: null,
            });
          });
      } else {
        res.json({
          code: CODE_ERROR,
          msg: "参数错误或数据不存在",
          data: null,
        });
      }
    });
  }
}

// 编辑批量任务
function editBatch(req, res, next) {
  const err = validationResult(req);
  if (!err.isEmpty()) {
    const [{ msg }] = err.errors;
    next(boom.badRequest(msg));
  } else {
    const dataArray = req.body;
    if (!dataArray || !Array.isArray(dataArray)) {
      res.json({
        code: CODE_ERROR,
        msg: "更新数据失败",
        data: null,
      });
      return;
    }
    const keys = ["key", "token", "guildId", "channelId", "status", "type", "remark", "maxUser"]; // 能修改的表头数据
    // 接口送什么修改什么，但是必须出现在列的地方
    const data = dataArray.map((item) => {
      const obj = {};
      Object.keys(item).forEach((key) => {
        if (keys.includes(key)) {
          if (key === "maxUser" && !item[key]) {
            return;
          }
          obj[key] = item[key];
        }
      });
      return obj;
    });
    // 构建 SQL 查询字符串
    const updateQueries = data.map((data) => {
      const updateFields = Object.entries(data).map(([key, value]) => {
        if (key === "status") {
          return `COALESCE(${!value ? 0 : 1}, status)`;
        }
        if (key === "type") {
          return `COALESCE(${value || 0}, type)`;
        }
        return `COALESCE('${value}', \`${key}\`)`;
      });
      return `(${updateFields.join(", ")})`;
    });

    const fullUpdateQuery = `INSERT INTO account (${Object.keys(data[0])
      .map((key) => `\`${key}\``)
      .join(", ")}) VALUES ${updateQueries.join(", ")} ON DUPLICATE KEY UPDATE ${Object.keys(data[0])
      .map((key) => `\`${key}\` = VALUES(\`${key}\`)`)
      .join(", ")}`;

    querySql(fullUpdateQuery)
      .then((data) => {
        // console.log('编辑任务===', data);
        if (!data || data.length === 0) {
          res.json({
            code: CODE_ERROR,
            msg: "更新数据失败",
            data: null,
          });
        } else {
          res.json({
            code: CODE_SUCCESS,
            msg: "更新数据成功",
            data: null,
          });
        }
      })
      .catch((err) => {
        res.json({
          code: CODE_ERROR,
          msg: "更新数据失败",
          data: null,
        });
      });
  }
}

// 删除任务
function remove(req, res, next) {
  const err = validationResult(req);
  if (!err.isEmpty()) {
    const [{ msg }] = err.errors;
    next(boom.badRequest(msg));
  } else {
    const { key: id } = req.body;
    queryOne(`select * from account where \`key\` = '${id}' and status = 1`).then((task) => {
      if (task) {
        const query = `update account set status = 0 where \`key\`='${id}'`;
        // const query = `delete from sys_task where id='${id}'`;
        querySql(query).then((data) => {
          // console.log('删除任务===', data);
          if (!data || data.length === 0) {
            res.json({
              code: CODE_ERROR,
              msg: "删除数据失败",
              data: null,
            });
          } else {
            res.json({
              code: CODE_SUCCESS,
              msg: "删除数据成功",
              data: null,
            });
          }
        });
      } else {
        res.json({
          code: CODE_ERROR,
          msg: "数据不存在",
          data: null,
        });
      }
    });
  }
}

// 删除任务
function removeBatch(req, res, next) {
  const err = validationResult(req);
  if (!err.isEmpty()) {
    const [{ msg }] = err.errors;
    next(boom.badRequest(msg));
  } else {
    const { ids } = req.body;
    if (!ids || !ids.length) {
      res.json({
        code: CODE_ERROR,
        msg: "删除数据不能为空",
        data: null,
      });
      return;
    }
    // 联合删除要合并
    querySql(
      `delete account, account_property from account left join account_property on account.key = account_property.id where account.key in (${ids
        .map((v) => `'${v}'`)
        .join(",")})`
    )
      .then((result) => {
        if (!result || result.affectedRows === 0) {
          res.json({
            code: CODE_ERROR,
            msg: "删除数据失败，数据不存在",
            data: null,
          });
        } else {
          res.json({
            code: CODE_SUCCESS,
            msg: "删除数据成功",
            data: null,
          });
        }
      })
      .catch((err) => {
        res.json({
          code: CODE_ERROR,
          msg: "删除数据失败",
          data: null,
        });
      });
  }
}

// 统计次数

// 查询id
function findByKey(req, res, next) {
  const err = validationResult(req);
  if (!err.isEmpty()) {
    const [{ msg }] = err.errors;
    next(boom.badRequest(msg));
  } else {
    let { key: id } = req.query;
    queryOne(`select * from account where \`key\` = '${id}' and status = 1`)
      .then((task) => {
        if (task) {
          updateCount(id);
          delete task.remark;
          delete task.createTime;

          res.json({
            code: CODE_SUCCESS,
            msg: "查询数据成功",
            data: task,
          });
        } else {
          res.json({
            code: CODE_ERROR,
            msg: "数据不存在",
            data: null,
          });
        }
      })
      .catch(() => {
        res.json({
          code: CODE_ERROR,
          msg: "数据不存在",
          data: null,
        });
      });
  }
}

// 加密token返回到客户端 治标不治本
function findByKeyV2(req, res, next) {
  const err = validationResult(req);
  if (!err.isEmpty()) {
    const [{ msg }] = err.errors;
    next(boom.badRequest(msg));
  } else {
    let { key: id, session = "", isLogin } = req.query;
    // 强制限制客户端升级
    if (!session) {
      res.json({
        code: CODE_FORBIDDEN,
        msg: "客户端版本过低请升级",
        data: null,
      });
      return;
    }
    queryOne(`select * from account where \`key\` = '${id}' and status = 1`)
      .then((task) => {
        if (task) {
          if (session) {
            if (isLogin) {
              querySql(`update account set session='${session}' where \`key\`='${id}'`)
                .then(() => {
                  updateCount(id);
                  const ob = {
                    ...task,
                    token: encrypt(task.token),
                  };
                  delete ob.remark;
                  delete ob.createTime;
                  res.json({
                    code: CODE_SUCCESS,
                    msg: "查询数据成功",
                    data: ob,
                  });
                })
                .catch(() => {
                  res.json({
                    code: CODE_ERROR,
                    msg: "数据不存在",
                    data: null,
                  });
                });
              return;
            }
            if (session !== task.session) {
              res.json({
                code: CODE_TOKEN_EXPIRED,
                msg: "用户在其他客户端登录",
                data: null,
              });
              return;
            }
          }
          updateCount(id);
          const ob = {
            ...task,
            token: encrypt(task.token),
          };
          delete ob.remark;
          delete ob.createTime;
          res.json({
            code: CODE_SUCCESS,
            msg: "查询数据成功",
            data: ob,
          });
        } else {
          res.json({
            code: CODE_ERROR,
            msg: "数据不存在",
            data: null,
          });
        }
      })
      .catch(() => {
        res.json({
          code: CODE_ERROR,
          msg: "数据不存在",
          data: null,
        });
      });
  }
}

// setCount
function updateCount(id) {
  const query = `INSERT INTO account_property (id, count) VALUES ('${id}', 1) ON DUPLICATE KEY UPDATE count = count + 1`;
  querySql(query);
}

// 通过任务名称或ID查询数据是否存在
function findTask(param) {
  let query = `select * from account where \`key\` = '${param}'`;
  return queryOne(query);
}

// 公告获取
function querySystem(req, res, next) {
  const err = validationResult(req);
  if (!err.isEmpty()) {
    const [{ msg }] = err.errors;
    next(boom.badRequest(msg));
    return;
  }
  const { id } = req.query;
  const query = `select * from system where \`id\` = ${id}`;
  queryOne(query)
    .then((task) => {
      if (task) {
        res.json({
          code: CODE_SUCCESS,
          msg: "查询数据成功",
          data: task,
        });
      } else {
        res.json({
          code: CODE_ERROR,
          msg: "数据不存在",
          data: null,
        });
      }
    })
    .catch(() => {
      res.json({
        code: CODE_ERROR,
        msg: "数据不存在",
        data: null,
      });
    });
}

// 更新公告
function updateSystem(req, res, next) {
  const err = validationResult(req);
  if (!err.isEmpty()) {
    const [{ msg }] = err.errors;
    next(boom.badRequest(msg));
  } else {
    const { id, content = "" } = req.body;
    let setStr = "";
    Object.keys(req.body).forEach((key) => {
      if (!["id", "content"].includes(key)) {
        setStr += `, ${key} = '${key}'`;
      }
    });
    const query = `update system set content='${content}' ${setStr} where \`id\`=${id}`;
    querySql(query)
      .then((data) => {
        if (!data || data.length === 0) {
          res.json({
            code: CODE_ERROR,
            msg: "更新数据失败",
            data: null,
          });
        } else {
          res.json({
            code: CODE_SUCCESS,
            msg: "更新数据成功",
            data: null,
          });
        }
      })
      .catch((err) => {
        res.json({
          code: CODE_ERROR,
          msg: "参数错误或数据不存在",
          data: null,
        });
      });
  }
}

module.exports = {
  queryPage,
  add,
  edit,
  editBase,
  editBatch,
  remove,
  findByKey,
  removeBatch,
  queryAll,
  findByKeyV2,
  querySystem,
  updateSystem,
};
